// ==UserScript== // @name Via Adblock 规则分析 // @namespace https://viayoo.com/ // @version 1.12 // @description 解析Adblock规则,是否值得在Via浏览器上订阅,评分仅供娱乐,自行斟酌。 // @author Grok & Via // @match *://* // @license MIT // @grant GM_registerMenuCommand // @run-at document-start // ==/UserScript== (function() { 'use strict'; console.log('Adblock Rule Analyzer 脚本已加载,URL:', location.href); // 注册菜单项 GM_registerMenuCommand("分析当前页面规则", analyzeCurrentPage); GM_registerMenuCommand("分析自定义链接规则", analyzeCustomLink); // 分析当前页面 async function analyzeCurrentPage() { console.log('分析当前页面'); let content; try { const response = await fetch(location.href); content = await response.text(); console.log('当前页面内容获取成功,长度:', content.length); } catch (e) { alert('无法获取当前页面内容: ' + e.message); console.error('当前页面内容获取失败:', e); return; } analyzeContent(content, '当前页面'); } // 分析自定义链接 function analyzeCustomLink() { console.log('分析自定义链接'); const url = prompt('请输入Adblock规则文件的直链(如 https://raw.githubusercontent.com/...)'); if (!url || !url.trim()) { alert('未输入有效的链接'); return; } fetch(url) .then(response => { if (!response.ok) throw new Error('网络请求失败,状态码: ' + response.status); return response.text(); }) .then(content => { console.log('自定义链接内容获取成功,长度:', content.length); analyzeContent(content, url); }) .catch(e => { alert('无法获取链接内容: ' + e.message); console.error('自定义链接内容获取失败:', e); }); } // 处理换行符,统一为 \n function normalizeNewlines(text) { return text.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); } // 通用分析函数 function analyzeContent(content, source) { if (!content.startsWith('[Adblock') && !content.startsWith('![Adblock')) { alert('这不是一个Adblock规则文件(未找到[Adblock开头),来源: ' + source); console.log('非Adblock文件,来源:', source); return; } content = normalizeNewlines(content); // 在传递内容之前统一处理换行符 const lines = content.split('\n') .filter(line => line.trim() !== '' && !line.trim().startsWith('!') && !line.trim().startsWith('[')); const stats = { cssRules: { normal: 0, exception: 0 }, domainRules: 0, unsupported: 0, extendedRules: { scriptInject: 0, adguardScript: 0, htmlFilter: 0, cssInject: 0, other: 0 } }; // uBlock/AdGuard 扩展规则模式 const extendedPatterns = { scriptInject: /(##|@#+)\+js\(/, adguardScript: /#@?%#/, htmlFilter: /\$\$/, cssInject: /#@?\$#/, other: /\$(\s*)(redirect|rewrite|csp|removeparam|badfilter|empty|generichide|match-case|object|object-subrequest|important|popup|document)|,(\s*)(redirect=|app=|replace=|csp=|denyallow=|permissions=)|:matches-path|:remove|redirect-rule/ }; lines.forEach(line => { const trimmed = line.trim(); if (trimmed.startsWith('##') || trimmed.startsWith('###')) { if (extendedPatterns.scriptInject.test(trimmed)) { stats.extendedRules.scriptInject++; stats.unsupported++; } else { stats.cssRules.normal++; } } else if (trimmed.startsWith('#@#') || trimmed.startsWith('#@##')) { if (extendedPatterns.scriptInject.test(trimmed)) { stats.extendedRules.scriptInject++; stats.unsupported++; } else { stats.cssRules.exception++; } } else if (trimmed.startsWith('#')) { if (extendedPatterns.adguardScript.test(trimmed)) { stats.extendedRules.adguardScript++; stats.unsupported++; } else if (extendedPatterns.cssInject.test(trimmed)) { stats.extendedRules.cssInject++; stats.unsupported++; } else { stats.unsupported++; } } else if (trimmed.startsWith('||')) { if (extendedPatterns.other.test(trimmed)) { stats.extendedRules.other++; stats.unsupported++; } else { stats.domainRules++; } } else if (extendedPatterns.htmlFilter.test(trimmed)) { stats.extendedRules.htmlFilter++; stats.unsupported++; } }); const totalCssRules = stats.cssRules.normal + stats.cssRules.exception; const totalExtendedRules = stats.extendedRules.scriptInject + stats.extendedRules.adguardScript + stats.extendedRules.htmlFilter + stats.extendedRules.cssInject + stats.extendedRules.other; let score = 0; // CSS规则评分(总分50) if (totalCssRules <= 7000) { score += 50; } else if (totalCssRules <= 9999) { score += 50 - ((totalCssRules - 7000) / 3000) * 25; // 线性递减 } else { score += 25 - ((totalCssRules - 9999) / 5000) * 10; // 超出9999的柔性扣分 } // 域名规则评分(总分40) if (stats.domainRules <= 100000) { score += 40; } else if (stats.domainRules <= 500000) { score += 40 - ((stats.domainRules - 100000) / 400000) * 20; // 新增档位 } else if (stats.domainRules <= 2000000) { score += 20 - ((stats.domainRules - 500000) / 1500000) * 20; } else { score = Math.max(1, score - ((stats.domainRules - 2000000) / 500000) * 10); // 超大规则集额外扣分 } // 扩展规则扣分(最多扣30分) if (totalExtendedRules > 500) { score -= 30; // 超过 500 条规则,直接扣满 30 分 } else if (totalExtendedRules > 100) { score -= 10 + ((totalExtendedRules - 100) / 400) * 15; // 超过 100 条但不超过 500 条,根据比例扣分,最多扣 25 分 } else if (totalExtendedRules > 0) { score += 0; // 保持现状,无扣分 } else { score += 10; // 没有扩展规则,额外加 10 分 } // 限制总分在 1 到 100 之间 score = Math.max(1, Math.min(100, Math.round(score))); // 优化后的 CSS 性能评估 let cssPerformance; if (totalCssRules <= 5000) { cssPerformance = '✅CSS规则数量正常,可以流畅运行'; } else if (totalCssRules <= 7000) { cssPerformance = '❓CSS规则数量较多,可能会导致设备运行缓慢'; } else if (totalCssRules < 9999) { cssPerformance = '⚠️CSS规则数量接近上限,可能明显影响设备性能'; } else { cssPerformance = '🆘CSS规则数量过多,不建议订阅此规则'; } // 优化后的域名规则评估 let domainPerformance; if (stats.domainRules <= 100000) { domainPerformance = '✅域名规则数量正常,可以流畅运行'; } else if (stats.domainRules <= 200000) { domainPerformance = '❓域名规则数量较多,但仍在可接受范围内'; } else if (stats.domainRules <= 500000) { domainPerformance = '🆘域名规则数量过多,可能会导致内存溢出 (OOM)'; } else { domainPerformance = '‼️域名规则数量极多,强烈不建议使用,可能严重影响性能'; } const report = ` Adblock规则分析结果(来源: ${source}): 💯规则评级: ${score}/100 (CSS规则占比最大,独有规则减分,域名规则次要) (评分仅供参考,具体以Via变动为主) --------------------- 📋CSS通用隐藏规则: 常规规则 (##, ###): ${stats.cssRules.normal} 例外规则 (#@#, #@##): ${stats.cssRules.exception} 总CSS规则数: ${totalCssRules} 性能评估: ${cssPerformance} 🔗域名规则 (||): ${stats.domainRules} 性能评估: ${domainPerformance} ✋🏼uBlock/AdGuard 独有规则: 脚本注入 (##+js): ${stats.extendedRules.scriptInject} AdGuard脚本 (#%#): ${stats.extendedRules.adguardScript} HTML过滤 ($$): ${stats.extendedRules.htmlFilter} CSS注入 (#$#): ${stats.extendedRules.cssInject} 其他扩展规则 ($redirect等): ${stats.extendedRules.other} 总计: ${totalExtendedRules} 👋不支持的规则: ${stats.unsupported} 🛠️总规则数: ${lines.length} 注:uBlock/AdGuard 独有规则在传统 Adblock Plus 中不受支持 `; alert(report); console.log(report); } })();